{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#  Convolutional Neural Network\n",
    "\n",
    "### Convolutional Layers: [128,128,128] ; Dense Layers [128,128,128] \n",
    "\n",
    "CNN is trained on raw data"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Get the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Stored variables and their in-db values:\n",
      "X_test              -> defaultdict(<class 'list'>, {0: array([[[  3.23910\n",
      "X_train             -> array([[[ -3.21133458e-03,  -1.31394120e-03,   5.5\n",
      "snrs                -> [-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, \n",
      "y_test              -> defaultdict(<class 'list'>, {0: array([4, 4, 5, ..\n",
      "y_train             -> array([2, 2, 4, ..., 3, 0, 5])\n"
     ]
    }
   ],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from collections import defaultdict\n",
    "from time import time\n",
    "\n",
    "%store -r\n",
    "%store"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training data:  (80000, 2, 128) and labels:  (80000,)\n",
      "\n",
      "Test data:\n",
      "Total 20 (4000, 2, 128) arrays for SNR values:\n",
      "[-20, -18, -16, -14, -12, -10, -8, -6, -4, -2, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18]\n"
     ]
    }
   ],
   "source": [
    "print(\"Training data: \", X_train.shape, \"and labels: \", y_train.shape)\n",
    "print()\n",
    "print(\"Test data:\")\n",
    "print(\"Total\", len(X_test), X_test[18].shape, \"arrays for SNR values:\")\n",
    "print(sorted(X_test.keys()))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "##  Standardize the features"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training set (80000, 2, 128)\n",
      "Test set corresponding to one snr value (4000, 2, 128)\n"
     ]
    }
   ],
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "sc = StandardScaler()\n",
    "_X_train = np.reshape(X_train, [X_train.shape[0], X_train.shape[1]*X_train.shape[2]])\n",
    "_X_train = sc.fit_transform(_X_train)\n",
    "\n",
    "X_train = np.reshape(_X_train, X_train.shape)\n",
    "print(\"Training set\", X_train.shape)\n",
    "\n",
    "_X_test = defaultdict(list)\n",
    "for snr in snrs:\n",
    "    _X_test[snr] = np.reshape(X_test[snr], [X_test[snr].shape[0], X_test[snr].shape[1]*X_test[snr].shape[2]])\n",
    "    _X_test[snr] = sc.transform(_X_test[snr])\n",
    "    X_test[snr] = np.reshape(_X_test[snr], X_test[snr].shape)\n",
    "    \n",
    "print(\"Test set corresponding to one snr value\", X_test[18].shape)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Design and train the CNN"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 0 training accuracy : 0.2919921875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Epoch 1 training accuracy : 0.3818359375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Epoch 2 training accuracy : 0.462890625\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Epoch 3 training accuracy : 0.5546875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Epoch 4 training accuracy : 0.5927734375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Epoch 5 training accuracy : 0.568359375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Epoch 6 training accuracy : 0.599609375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Epoch 7 training accuracy : 0.5966796875\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Epoch 8 training accuracy : 0.64453125\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Epoch 9 training accuracy : 0.6630859375\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Training took 39.438687 minutes\n"
     ]
    }
   ],
   "source": [
    "height = 2\n",
    "width = 128\n",
    "channels = 1\n",
    "n_features = height * width\n",
    "\n",
    "feature_map1 = 128\n",
    "ksize_conv1 = 2\n",
    "stride_conv1 = 1\n",
    "\n",
    "feature_map2 = 128\n",
    "ksize_conv2 = ksize_conv1\n",
    "stride_conv2 = stride_conv1\n",
    "\n",
    "feature_map3 = 128\n",
    "ksize_conv3 = ksize_conv1\n",
    "stride_conv3 = stride_conv1\n",
    "\n",
    "pool_layer_maps = 128\n",
    "\n",
    "n_fully_conn1 = 128\n",
    "n_fully_conn2 = 128\n",
    "n_fully_conn3 = 128\n",
    "\n",
    "n_classes = 8\n",
    "  \n",
    "X = tf.placeholder(tf.float32, shape=[None, height, width])\n",
    "X_reshaped = tf.reshape(X, shape=[-1, height, width, channels])\n",
    "labels = tf.placeholder(tf.int32, shape=[None])\n",
    "training_ = tf.placeholder_with_default(False, shape=[])\n",
    "\n",
    "xavier_init = tf.contrib.layers.xavier_initializer()\n",
    "relu_act = tf.nn.relu\n",
    "\n",
    "# ------------------ Convolutional and pooling layers ----------------------------\n",
    "\n",
    "def convolutional_layer(X, filter_, ksize, kernel_init, strides, padding):\n",
    "    convolutional_layer = tf.layers.conv2d(X, filters = filter_, kernel_initializer = kernel_init,\n",
    "                                           kernel_size = ksize, strides = strides,\n",
    "                                          padding = padding, activation = relu_act)\n",
    "    return convolutional_layer\n",
    "\n",
    "def pool_layer(convlayer, ksize, strides, padding, pool_maps):\n",
    "    pool = tf.nn.max_pool(convlayer, ksize, strides, padding)\n",
    "    dim1, dim2 = int(pool.get_shape()[1]), int(pool.get_shape()[2])\n",
    "    pool_flat = tf.reshape(pool, shape = [-1, pool_maps * dim1 * dim2])\n",
    "    return pool_flat\n",
    "\n",
    "conv_layer1 = convolutional_layer(X_reshaped, feature_map1, ksize_conv1, xavier_init, stride_conv1, padding = \"SAME\")\n",
    "\n",
    "conv_layer2 = convolutional_layer(conv_layer1, feature_map2, ksize_conv2, xavier_init, stride_conv2, padding = \"SAME\")\n",
    "\n",
    "conv_layer3 = convolutional_layer(conv_layer2, feature_map3, ksize_conv3, xavier_init, stride_conv3, padding = \"SAME\")\n",
    "\n",
    "pool_layer_flat = pool_layer(conv_layer3, [1,2,2,1], [1,2,2,1], \"VALID\", pool_layer_maps)\n",
    "\n",
    "# ----------------- Fully connected layers -------------------\n",
    "\n",
    "def dense_layer(input_layer, n_neurons, kernel_init, activation):\n",
    "    fully_conn = tf.layers.dense(inputs = input_layer, units = n_neurons, activation = activation,\n",
    "                                kernel_initializer = kernel_init)\n",
    "    return fully_conn\n",
    "        \n",
    "dense_layer1 = dense_layer(pool_layer_flat, n_fully_conn1, xavier_init, relu_act)\n",
    "\n",
    "dense_layer2 = dense_layer(dense_layer1, n_fully_conn2, xavier_init, relu_act)\n",
    "\n",
    "dense_layer3 = dense_layer(dense_layer2, n_fully_conn3, xavier_init, relu_act)\n",
    "\n",
    "# ----------------- Output softmax layer ---------------------------\n",
    "\n",
    "logits = tf.layers.dense(dense_layer3, n_classes)\n",
    "softmax_activations = tf.nn.softmax(logits)\n",
    "\n",
    "# ----------------- Specify performance measure -------------------------------\n",
    "\n",
    "cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = logits, labels = labels)\n",
    "loss = tf.reduce_mean(cross_entropy)\n",
    "optimizer = tf.train.AdamOptimizer()\n",
    "train_operation = optimizer.minimize(loss)\n",
    "\n",
    "correct_predictions = tf.nn.in_top_k(logits, labels, 1)\n",
    "accuracy = tf.reduce_mean(tf.cast(correct_predictions, tf.float32))\n",
    "\n",
    "# ---------------- Execution phase -------------------------------------------\n",
    "    \n",
    "n_epochs = 10\n",
    "batch_size = 1024\n",
    "n_train = X_train.shape[0]\n",
    "n_iter = n_train//batch_size\n",
    "\n",
    "acc_test = defaultdict(list)\n",
    "\n",
    "path = \"./CNN_narrow_deep5\"  \n",
    "saver = tf.train.Saver()\n",
    "\n",
    "start = time()\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    tf.global_variables_initializer().run()\n",
    "    for epoch in range(n_epochs):\n",
    "        for iteration in range(n_iter):\n",
    "            rand_indices = np.random.choice(n_train,batch_size)    \n",
    "            X_batch, y_batch = X_train[rand_indices], y_train[rand_indices]\n",
    "            sess.run(train_operation, feed_dict={X: X_batch, labels: y_batch, training_: True})\n",
    "        acc_train = accuracy.eval(feed_dict={X: X_batch, labels: y_batch})\n",
    "        print(\"Epoch {} training accuracy : {}\".format(epoch, acc_train))\n",
    "        save_path = saver.save(sess, path)\n",
    "        saver.restore(sess, path)\n",
    "    saver.restore(sess, path)\n",
    "    for snr in snrs:\n",
    "        acc_test[snr] = accuracy.eval(feed_dict={X: X_test[snr], labels: y_test[snr]})\n",
    "\n",
    "print(\"Training took %f minutes\"%(float(time() - start)/60.0))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Test the classifier"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "CNN's test accuracy on -20dB SNR samples = 0.12399999797344208\n",
      "CNN's test accuracy on -18dB SNR samples = 0.13124999403953552\n",
      "CNN's test accuracy on -16dB SNR samples = 0.1315000057220459\n",
      "CNN's test accuracy on -14dB SNR samples = 0.14024999737739563\n",
      "CNN's test accuracy on -12dB SNR samples = 0.1652500033378601\n",
      "CNN's test accuracy on -10dB SNR samples = 0.19900000095367432\n",
      "CNN's test accuracy on -8dB SNR samples = 0.2615000009536743\n",
      "CNN's test accuracy on -6dB SNR samples = 0.36625000834465027\n",
      "CNN's test accuracy on -4dB SNR samples = 0.49775001406669617\n",
      "CNN's test accuracy on -2dB SNR samples = 0.6672499775886536\n",
      "CNN's test accuracy on 0dB SNR samples = 0.7590000033378601\n",
      "CNN's test accuracy on 2dB SNR samples = 0.7962499856948853\n",
      "CNN's test accuracy on 4dB SNR samples = 0.8159999847412109\n",
      "CNN's test accuracy on 6dB SNR samples = 0.8057500123977661\n",
      "CNN's test accuracy on 8dB SNR samples = 0.8144999742507935\n",
      "CNN's test accuracy on 10dB SNR samples = 0.815750002861023\n",
      "CNN's test accuracy on 12dB SNR samples = 0.8205000162124634\n",
      "CNN's test accuracy on 14dB SNR samples = 0.8112499713897705\n",
      "CNN's test accuracy on 16dB SNR samples = 0.8147500157356262\n",
      "CNN's test accuracy on 18dB SNR samples = 0.8217499852180481\n"
     ]
    }
   ],
   "source": [
    "for snr in snrs:\n",
    "    print(\"CNN's test accuracy on {}dB SNR samples = {}\".format(snr,acc_test[snr]))  "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Visualize classifier's performance on test set"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n7quir6nbS0REREIvrcOUZvZFYIy7T45uTwBGu/uUOMf+CnhMw5QiIiKS67JpnbF4jfjAFdXEiRMp\nL8+WCXAAAA7SSURBVC8HoKysjFGjRu38BmJr96O2ta1tbWtb29rWdrq3W59XV1fTKXdP2wM4Fngy\nZvtqYFoHx/4KODvBuTydFixYoDzlZV2W8pSnvPzJC/O15UNetG6JW9MUdF6udavFwAgzO8DMioFx\nwKMJju/8BosiIiIiOSxTS1vcxq6lLW4ysxnAYnd/3Mw+BjwClAH1wFp3PzzOeTzdbRcRERH5ILJq\nnbHuomJMREREckXWrDOWy2In5ClPedmSpTzlKS9/8sJ8bfmQl4iKMREREZEM0jCliIiISIppmFJE\nREQkS6kYS1LYx7KVl5tZylOe8vInL8zXlg95iagYExEREckgzRkTERERSTHNGRMRERHJUirGkhT2\nsWzl5WaW8pSnvPzJC/O15UNeIirGRERERDJIc8ZEREREUkxzxkRERESylIqxJIV9LFt5uZmlPOUp\nL3/ywnxt+ZCXiIoxERERkQzSnDERERGRFNOcMREREZEspWIsSWEfy1ZebmYpT3nKy5+8MF9bPuQl\nomJMREREJIM0Z0xEREQkxTRnTERERCRLqRhLUtjHspWXm1nKU57y8icvzNeWD3mJqBgTERERySDN\nGRMRERFJMc0ZExEREclSaS/GzGysmb1uZsvNbFqc14vN7EEze9PMFpnZ/uluYzxhH8tWXm5mKU95\nysufvDBfWz7kJZLWYszMCoCfAWOAw4DxZvbhNoedD2x09w8BtwKz09nGjixZskR5ysu6LOUpT3n5\nkxfma8uHvETS3TM2GnjT3Ve6exPwIHBGm2POAO6NPn8YODmN7etQbW2t8pSXdVnKU57y8icvzNeW\nD3mJpLsYGw68E7P9bnRf3GPcPQLUmtnA9DRPREREJL3SXYzF+xZB269Etj3G4hyTdtXV1cpTXtZl\nKU95ysufvDBfWz7kJZLWpS3M7FjgBncfG92+GnB3vznmmD9Hj3nOzAqBNe6+V5xzZbxAExEREUlW\nR0tb9EhzOxYDI8zsAGANMA4Y3+aYx4BzgeeALwNPxTtRRxckIiIikkvSWoz9//bOPNaq6orD3w/f\nUwEFx0otRbQVx4pTkSqKrdSgttRUTRRbUTukRivVKIqYONTWoSoYE/+oRW2xtCgOVasg4FCtoqLM\n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\nrkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f79ad8afcc0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.style.use('classic')\n",
    "%matplotlib inline\n",
    "\n",
    "acc_test = sorted(acc_test.items())\n",
    "new_acc = []\n",
    "for i in range(len(acc_test)):\n",
    "    new_acc.append(acc_test[i][1])\n",
    "acc_test_values = new_acc \n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "x = snrs\n",
    "y = list(acc_test_values)\n",
    "plt.plot(x, y, marker=\"o\", linewidth=2.0, linestyle='dashed', color='royalblue')\n",
    "plt.axis([-20, 20, 0, 1])\n",
    "plt.xticks(np.arange(min(x), max(x)+1, 2.0))\n",
    "plt.yticks(np.arange(0, 1, 0.10))\n",
    "\n",
    "ttl = plt.title('SNR vs Accuracy', fontsize=16)\n",
    "ttl.set_weight('bold')\n",
    "plt.xlabel('SNR (dB)', fontsize=14)\n",
    "plt.ylabel('Test accuracy', fontsize=14)\n",
    "plt.grid()\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "INFO:tensorflow:Restoring parameters from ./CNN_narrow_deep5\n",
      "Confusion Matrix\n",
      "       8PSK  BPSK  CPFSK  GFSK  PAM4  QAM16  QAM64  QPSK\n",
      "8PSK   0.81  0.00   0.00  0.00  0.00   0.04   0.03  0.12\n",
      "BPSK   0.00  0.97   0.00  0.00  0.01   0.01   0.00  0.01\n",
      "CPFSK  0.01  0.00   0.97  0.00  0.00   0.00   0.00  0.00\n",
      "GFSK   0.01  0.00   0.02  0.97  0.00   0.00   0.00  0.00\n",
      "PAM4   0.00  0.01   0.00  0.00  0.98   0.01   0.00  0.00\n",
      "QAM16  0.04  0.00   0.00  0.00  0.00   0.49   0.46  0.01\n",
      "QAM64  0.00  0.00   0.00  0.00  0.00   0.42   0.57  0.00\n",
      "QPSK   0.13  0.01   0.00  0.00  0.00   0.02   0.01  0.83\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f794066df28>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Confusion Matrix\n",
    "\n",
    "with tf.Session() as sess:\n",
    "    saver.restore(sess, path)\n",
    "    Z = logits.eval(feed_dict = {X : X_test[18]})\n",
    "    predicted_18dB = np.argmax(Z, axis = 1)\n",
    "    \n",
    "from sklearn.metrics import confusion_matrix\n",
    "%matplotlib inline\n",
    "\n",
    "classes = ['8PSK', 'BPSK', 'CPFSK', 'GFSK', 'PAM4', 'QAM16', 'QAM64', 'QPSK']\n",
    "conf_matrix = confusion_matrix(predicted_18dB, y_test[18])  \n",
    "\n",
    "conf_matrix = conf_matrix.astype('float') / conf_matrix.sum(axis=1)[:, np.newaxis]\n",
    "conf_matrix = conf_matrix.round(decimals = 2)\n",
    "\n",
    "import pandas as pd\n",
    "\n",
    "df = pd.DataFrame(data = conf_matrix, columns = classes, index = classes) \n",
    "print(\"Confusion Matrix\")\n",
    "print(df)\n",
    "\n",
    "fig1 = plt.figure(figsize=(10, 6), dpi=100)\n",
    "plt.imshow(conf_matrix, interpolation = 'nearest', cmap = plt.cm.Purples)\n",
    "ticks = np.arange(len(classes))\n",
    "plt.title(\"Confusion Matrix\")\n",
    "plt.xticks(ticks, classes, rotation=45)\n",
    "plt.yticks(ticks, classes)\n",
    "\n",
    "plt.ylabel('True class')\n",
    "plt.xlabel('Predicted class')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.colorbar()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  },
  "widgets": {
   "state": {},
   "version": "1.1.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
